﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Common {
    public abstract class GlDisposableObjectBase : IDisposable {
        public GlDisposableObjectBase() {

        }
    
        bool disposed;
        public void Dispose() {
            GC.SuppressFinalize(this);
            if (!disposed) {
                OnDispose();
            }
            disposed = true;
        }

        protected abstract void OnDispose();

        ~GlDisposableObjectBase() {
            if (!disposed) {
                string typeDescription = GetPrettyTypeName(this.GetType());
                throw new EngineException($"resource {typeDescription} not disposed");
            }
        }

 

        static string GetPrettyTypeName(Type t) {
            if (t.IsGenericType) {
                return string.Format(
                    "{0}<{1}>",
                    t.Name.Substring(0, t.Name.LastIndexOf("`", StringComparison.InvariantCulture)),
                    string.Join(", ", t.GenericTypeArguments.Select(GetPrettyTypeName)));
            }

            return t.Name;
        }

        public static void DisposeObjects(params GlDisposableObjectBase[] disposableObjects) {
            foreach (var item in disposableObjects) {
                if (item != null) {
                    item.Dispose();
                }
            }
        }
        public static void DisposeAllDisposableMembers(object obj) {
            DisposeHelper.DisposeAllDisposableMembers(obj);
        }
        //    Type t = obj.GetType();
        //    var fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        //    //foreach (var field in fields) {
        //    //    if (isIDisposeable(field)){
        //    //        disposeField(obj, field);
        //    //    }
        //    //}
        //    List<FieldInfo> fieldList = new List<FieldInfo>(fields);
            

        //    fields.Foreach((FieldInfo field) =>
        //    {
        //        if (isIDisposeable(field)){
        //            disposeField(obj, field);
        //        }
        //    });
        //}

        //private static void disposeField(object obj, FieldInfo field) {
        //    var fieldInstance=field.GetValue(obj);
        //    IDisposable disposableField = (IDisposable)fieldInstance;
        //    disposableField.Dispose();
        //}

        //private static bool isIDisposeable(FieldInfo field) {
        //    var fieldType = field.FieldType;
        //    if (fieldType.GetInterface("System.IDisposable") == null) {
        //        return false;
        //    } else {
        //        return true;
        //    }
        //}
    }
}
